<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2显式原型与隐式原型</title>
</head>

<body>
    <!-- 
        1. 每个函数function都有一个prototype，即显式原型（属性）
        2. 每个实例对象都有一个__proto__，可称为隐式原型（属性）
        3. 对象的隐式原型的值为其对应构造函数的显式原型的值
        4. 总结：
            函数的prototype属性：在定义函数式自动添加，默认值是一个空Object对象
            对象的__proto__属性：创建对象时自动添加，默认值为构造函数的prototype属性值
            我们能直接操作显式原型，但不能直接操作隐式原型（ES6之前）
     -->
    <script>
        // 定义函数时，底层会相当于执行this.prototype = {}
        function Fn() {

        }
        // 1. 每个函数function都有一个prototype，即显式原型（属性）
        console.log(Fn.prototype);
        // 底层执行this.__proto__ = Fn.prototype
        let fn = new Fn()
        // 2. 每个实例对象都有一个__proto__，可称为隐式原型（属性）
        console.log(fn.__proto__)
        // 3. 对象的隐式原型的值为其对应构造函数的显式原型的值
        console.log(fn.__proto__ === Fn.prototype)

        Fn.prototype.test = function () {
            console.log('test')
        }
        console.log(fn.test)
        console.log(typeof fn.test())
    </script>
</body>

</html>